package com.hlw.springboot.controller;

import com.hlw.springboot.entity.SysPermission;
import com.hlw.springboot.entity.SysRole;
import com.hlw.springboot.entity.SysUser;
import com.hlw.springboot.mapper.SysPermissionMapper;
import com.hlw.springboot.mapper.SysRoleMapper;
import com.hlw.springboot.mapper.SysUserMapper;
import com.hlw.springboot.util.DataResult;
import com.hlw.springboot.util.IpConfig;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


@RestController
public class LoginController {

    @Resource
    private SysRoleMapper sysRoleMapper;
    @Resource
    private SysPermissionMapper sysPermissionMapper;
    @Resource
    private SysUserMapper sysUserMapper;




    // 这里如果不写method参数的话，默认支持所有请求，如果想缩小请求范围，还是要添加method来支持get, post等等某个请求。
    //登录方法
    @RequestMapping(value="/syslogin",method=RequestMethod.POST)
    public DataResult toLogin(String username, String password, Model model){

        UsernamePasswordToken token =new UsernamePasswordToken(username,password);
        Subject subject = SecurityUtils.getSubject();
        try {
            //这里直接使用shiro的登录方法
            subject.login(token);
            SysUser user = (SysUser) SecurityUtils.getSubject().getPrincipal();
            user.setLocalip(IpConfig.localIp());
            sysUserMapper.updateByPrimaryKey(user);//每次登录更新IP
            return new DataResult(0,"登录成功",user);
            //登录失败时，会catch到你的异常，异常通过全局处理
        } catch (UnknownAccountException e) {
            return new DataResult(401,"该账号不存在");
        } catch (IncorrectCredentialsException e) {
            System.out.println(e);
            return new DataResult(401,"密码错误，请重试");
        } catch (LockedAccountException e) {
            return new DataResult(401,"该账户已被锁定,请联系管理员");
        } catch (Exception e) {
            return new DataResult(401,"登录失败");
        }
    }



        /**
         * 进入首页后加载菜单树
         */
        @RequestMapping("/current")
        @ResponseBody
        public DataResult findPermission() {
            SysUser user = (SysUser) SecurityUtils.getSubject().getPrincipal();
            if(user!=null){
                List<SysPermission> list = sysPermissionMapper.listByUserId(user.getId());//根据用户id获取权限

                final List<SysPermission> permissions = list.stream().filter(l -> l.getType().equals(0))
                        .collect(Collectors.toList());

                List<SysPermission> firstLevel = permissions.stream().filter(p -> p.getParentId().equals(0) && p.getDelflag().equals(0)).collect(Collectors.toList());
                firstLevel.parallelStream().forEach(p -> {
                    setChild(p, permissions);
                });
                return new DataResult(0,"成功获取权限",firstLevel);
            }else {
                return  new DataResult(404,"获取失败");
            }

        }

    /**
     * 设置子元素
     * 2018.06.09
     *
     * @param p
     * @param permissions
     */
    private void setChild(SysPermission p, List<SysPermission> permissions) {
        List<SysPermission> child = permissions.parallelStream().filter(a -> a.getParentId().equals(p.getId())).collect(Collectors.toList());
        p.setChild(child);
        if (!CollectionUtils.isEmpty(child)) {
            child.parallelStream().forEach(c -> {
                //递归设置子元素，多级菜单支持
                setChild(c, permissions);
            });
        }
    }



}
